package com.qire.common.widget.adapter.auto;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import com.qire.common.basic.ObjectUtil;
import com.qire.common.collect.ListUtil;
import com.qire.common.widget.adapter.auto.annotation.AdapterEntityBind;

import java.util.HashMap;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;

/**
 * 带布局类型区分的自动绑定Adapter,适用于多布局组合的AdapterView
 * @param <T> 用于自动适配的 ViewModel 类型
 */
public class SummerWithTypeBindAdapter <T extends AutoVariable> extends BaseAdapter {

    /** 用于缓存ViewHolder到RootView的Tag */
    private static final int HOLDER_TAG = 3 << 24;

    /** ViewModel数据列表 */
    private final List<T> dataList;

    /** 事件处理器 */
    private AutoVariable eventProcess;

    /** 缓存布局的RID */
    private final HashMap<String, Integer> viewLayoutIdMap = new HashMap<>();

    /**
     * @param dataList 包含子项数据的ViewModel
     */
    public SummerWithTypeBindAdapter(@NonNull List<T> dataList) {
        this(dataList, null);
    }

    /**
     * @param dataList 包含子项数据的ViewModel
     * @param eventProcess 设置给子项绑定的事件处理器
     */
    public SummerWithTypeBindAdapter(@NonNull List<T> dataList, AutoVariable eventProcess) {
        this.dataList = dataList;
        this.eventProcess = eventProcess;
    }

    /**
     * 设置事件处理器到所有项目View并进行绑定
     * @param eventProcess 事件处理器
     */
    public void setEventProcess(AutoVariable eventProcess) {
        this.eventProcess = eventProcess;
        notifyDataSetChanged();
    }

    /**
     * 获取所有数据列表
     * @return viewModel 数据列表
     */
    public List<T> getDataList() {
        return dataList;
    }

    /**
     * 获取所有项目的数量，如果列表为NULL则返回0
     * @return 子项目统计数
     */
    @Override
    public int getCount() {
        return dataList == null ? 0 : dataList.size();
    }

    @Override
    public Object getItem(int position) {
        return dataList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getViewTypeCount() {
        return Math.max(1, viewLayoutIdMap.size());
    }

    @Override
    public int getItemViewType(int position) {
        return fetchRootViewId(position);
    }

    /**
     * 通过ViewModel提取layoutRid，如果dataList为空，则无法提取会并会导致后续异常
     * @return layoutRid
     */
    private int fetchRootViewId(int position) {
        if(ListUtil.isEmpty(dataList)) {
            return 0;
        }

        T data = ListUtil.range(dataList, position) ? dataList.get(position) : null;
        if(ObjectUtil.isNull(data)) {
            return 0;
        }

        Class<?> dataClass = data.getClass();
        String className = dataClass.getCanonicalName();

        if(viewLayoutIdMap.containsKey(className)) {
            return viewLayoutIdMap.get(className);
        }

        if(dataClass.isAnnotationPresent(AdapterEntityBind.class)) {
            AdapterEntityBind adapterEntityBind = dataClass.getAnnotation(AdapterEntityBind.class);
            int viewLayoutId = adapterEntityBind.viewRid();
            viewLayoutIdMap.put(className, viewLayoutId);
            return viewLayoutId;
        }

        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        // 获取ViewHolder缓存
        ViewHolder viewHolder = convertView == null ? null : (ViewHolder) convertView.getTag(HOLDER_TAG);

        // 如果ViewHolder缓存不存在，进入ViewHolder构建流程
        if(viewHolder == null) {
            // 从当前View中获取viewDataBinder
            ViewDataBinding binding = DataBindingUtil.getBinding(convertView);
            // 如果 viewDataBinder 不存在则，则说明 convertView 未创建或则 convertView 并非通过 dataBind 创建，重建 convertView 通过dataBind
            if(binding == null) {
                LayoutInflater inflater = LayoutInflater.from(parent.getContext());
                binding = DataBindingUtil.inflate(inflater, fetchRootViewId(position),parent,false);
                convertView = binding.getRoot();
            }
            // 构建ViewHolder
            viewHolder = new ViewHolder(binding);
            // 缓存ViewHolder，为了使重复使用时，能获得View，所以这里吧构造好的ViewHolder保存起来。
            convertView.setTag(HOLDER_TAG, viewHolder);
        }

        // 获得对应位置的数据
        T data = dataList.get(position);

        // 绑定替换原 convertView 的内容 viewModel
        viewHolder.bindData(data);
        // 绑定替换原 convertView 的内容 eventProcess
        viewHolder.bindData(eventProcess);

        return convertView;
    }

    /**
     * 缓存binder的处理器，负责绑定数据
     */
    protected class ViewHolder {
        protected final ViewDataBinding viewDataBinding;

        public ViewHolder(ViewDataBinding viewDataBinding) {
            this.viewDataBinding = viewDataBinding;
        }

        public void bindData(AutoVariable observable) {
            if(observable != null) {
                observable.bindVariable(viewDataBinding);
            }
        }
    }

}
